﻿using Abp.Authorization;
using Microsoft.EntityFrameworkCore;
using Mt.Site.Application.AccessStatistics.Dto;
using Mt.Site.Core.AccessStatistics.Permissions;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Application.AccessStatistics
{
    //访客分析 partial
    partial class VisitStatisticAppService
    {
        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<VisitorRegionOut> GetVisitorRegionAnalysis(VisitorRegionInput input)
        {
            var startTime = input.StartTime;
            var endTime = input.EndTime;
            if (!_visitStatisticHelper.CheckTimeFormat(ref startTime, ref endTime))
            {
                return null;
            }
            var visitorRegionDto = new VisitorRegionOut();
            input.StartTime = startTime;
            input.EndTime = endTime;
            visitorRegionDto.StartTime = startTime.ToString("yyyy-MM-dd");
            visitorRegionDto.EndTime = endTime.ToString("yyyy-MM-dd");
            visitorRegionDto.AvgVisitTime = "00:00:00";
            visitorRegionDto.IpNum = 0;
            visitorRegionDto.NewNum = 0;
            visitorRegionDto.OutRate = 0;
            visitorRegionDto.PvNum = 0;
            visitorRegionDto.UvNum = 0;
            var outNumber = 0;
            var lengthOfStay = 0;
            var TenancyName = GetCurrentTenant().TenancyName;
            var ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorAreaAnalysisQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Area = data.Region } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Area = t.Key.Area
                              }
                          group dataTwo by new { Area = dataTwo.Area } into tTwo
                          select new
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Area = tTwo.Key.Area
                          };

            var query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorAreaAnalysisQuery(input, TenancyName)
                            group data by new { Area = data.Region, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Area = t.Key.Area,
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Area = dataTwo.Area } into tTwo
                        select new
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Area = tTwo.Key.Area
                        };

            var ipList = await ipQuery.ToListAsync();
            var list = await query.ToListAsync();

            var visitorRegionItems = new List<VisitorRegionItem>();
            foreach (var item in list)
            {
                var VisitorRegionItem = new VisitorRegionItem();
                VisitorRegionItem.Area = item.Area;
                VisitorRegionItem.UvNum = item.UvNum;
                VisitorRegionItem.PvNum = item.PvNum;
                VisitorRegionItem.NewNum = item.NewNum;
                VisitorRegionItem.LengthOfStay = item.LengthOfStay;
                VisitorRegionItem.OutRate = _visitStatisticHelper.BounceRateCalc(item.OutNum, item.PvNum);
                VisitorRegionItem.AvgVisitTime = _visitStatisticHelper.NumberToTime(item.LengthOfStay, item.PvNum, item.OutNum);

                visitorRegionDto.UvNum += item.UvNum;
                visitorRegionDto.PvNum += item.PvNum;
                visitorRegionDto.NewNum += item.NewNum;
                lengthOfStay += item.LengthOfStay;
                outNumber += item.OutNum;

                foreach (var p in ipList)
                {
                    if (item.Area == p.Area)
                    {
                        VisitorRegionItem.IpNum = p.IpNum;
                        visitorRegionDto.IpNum += p.IpNum;
                    }
                }
                visitorRegionItems.Add(VisitorRegionItem);
            }


            visitorRegionDto.OutRate = _visitStatisticHelper.BounceRateCalc(outNumber, visitorRegionDto.PvNum);
            visitorRegionDto.AvgVisitTime = _visitStatisticHelper.NumberToTime(lengthOfStay, visitorRegionDto.PvNum, outNumber);
            visitorRegionDto.VisitorRegionItems = visitorRegionItems;
            return visitorRegionDto;
        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<List<VisitorAreaDetailItem>> GetVisitorDetailRegionOrIsp(VisitorAreaOrIpsInut input)
        {
            var startTime = input.StartTime;
            var endTime = input.EndTime;
            if (!_visitStatisticHelper.CheckTimeFormat(ref startTime, ref endTime))
            {
                return null;
            }
            input.StartTime = startTime;
            input.EndTime = endTime;
            IQueryable<ClientIpQueryDto> ipQuery = null;
            IQueryable<AccoutDetailQueryDto> query = null;
            var TenancyName = GetCurrentTenant().TenancyName;
            if (input.IsByRegion)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorCityOrIspDetailQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.City } into t
                              select new 
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorCityOrIspDetailQuery(input, TenancyName)
                            group data by new { Label = data.City, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label,
                                PvNum = t.Count(),
                                outNum = t.Sum(item => item.IsBounced),
                                newNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.newNum),
                            OutNum = tTwo.Sum(item => item.outNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            else
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorCityOrIspDetailQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.ISP } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorCityOrIspDetailQuery(input, TenancyName)
                            group data by new { Label = data.ISP, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label,
                                PvNum = t.Count(),
                                outNum = t.Sum(item => item.IsBounced),
                                newNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.newNum),
                            OutNum = tTwo.Sum(item => item.outNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            

            var ipList = await ipQuery.ToListAsync();
            var list = await query.ToListAsync();

            var visitorAreaDetailItems = new List<VisitorAreaDetailItem>();
            foreach (var item in list)
            {
                var VisitorAreaDetailItem = new VisitorAreaDetailItem();
                VisitorAreaDetailItem.Name = item.Label;
                VisitorAreaDetailItem.UvNum = item.UvNum;
                VisitorAreaDetailItem.PvNum = item.PvNum;
                VisitorAreaDetailItem.NewNum = item.NewNum;
                VisitorAreaDetailItem.LengthOfStay = item.LengthOfStay;
                VisitorAreaDetailItem.OutRate = _visitStatisticHelper.BounceRateCalc(item.OutNum, item.PvNum);
                VisitorAreaDetailItem.AvgVisitTime = _visitStatisticHelper.NumberToTime(item.LengthOfStay, item.PvNum, item.OutNum);

                foreach (var p in ipList)
                {
                    if (item.Label == p.Label)
                    {
                        VisitorAreaDetailItem.IpNum = p.IpNum;
                    }
                }
                visitorAreaDetailItems.Add(VisitorAreaDetailItem);
            }


            return visitorAreaDetailItems;
        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<SystemEnvOut> GetSystemEnvAnalysis(SystemEnvInput input)
        {
            var startTime = input.StartTime;
            var endTime = input.EndTime;
            if (!_visitStatisticHelper.CheckTimeFormat(ref startTime, ref endTime))
            {
                return null;
            }
            var SystemEnvOut = new SystemEnvOut();
            input.StartTime = startTime;
            input.EndTime = endTime;
            SystemEnvOut.StartTime = startTime.ToString("yyyy-MM-dd");
            SystemEnvOut.EndTime = endTime.ToString("yyyy-MM-dd");
            SystemEnvOut.AvgVisitTime = "00:00:00";
            SystemEnvOut.IpNum = 0;
            SystemEnvOut.NewNum = 0;
            SystemEnvOut.OutRate = 0;
            SystemEnvOut.PvNum = 0;
            SystemEnvOut.UvNum = 0;
            var outNumber = 0;
            var lengthOfStay = 0;

            IQueryable<ClientIpQueryDto> ipQuery = null;
            IQueryable<AccoutDetailQueryDto> query = null;
            var TenancyName = GetCurrentTenant().TenancyName;
            if (input.SystemEnvType == SystemEnvType.Browser)
            {
                 ipQuery = from dataTwo in
                                  from data in _AccessDataRespository.GetAll()
                                  .VisitorSystemEnvQuery(input, TenancyName)
                                  group data by new { Ip = data.ClientIp, Label = data.FormFactor } into t
                                  select new
                                  {
                                      Ip = t.Key.Ip,
                                      Label = t.Key.Label.ToString()
                                  }
                              group dataTwo by new { Label = dataTwo.Label } into tTwo
                              select new ClientIpQueryDto
                              {
                                  IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                  Label = tTwo.Key.Label
                              };

               query = from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                                .VisitorSystemEnvQuery(input, TenancyName)
                                group data by new { Label = data.FormFactor, Accout = data.Acount } into t
                                select new
                                {
                                    Account = t.Key.Accout,
                                    Label = t.Key.Label.ToString(),
                                    PvNum = t.Count(),
                                    OutNum = t.Sum(item => item.IsBounced),
                                    NewNum = t.Sum(item => item.IsNewVisitor),
                                    LengthOfStay = t.Sum(item => item.LengthOfStay)
                                }
                            group dataTwo by new { Label = dataTwo.Label } into tTwo
                            select new AccoutDetailQueryDto
                            {
                                UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                                PvNum = tTwo.Sum(item => item.PvNum),
                                NewNum = tTwo.Sum(item => item.NewNum),
                                OutNum = tTwo.Sum(item => item.OutNum),
                                LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                                Label = tTwo.Key.Label
                            };
            }
            else if (input.SystemEnvType == SystemEnvType.NetworkDevices)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.FormFactor } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label.ToString()
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.FormFactor, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label.ToString(),
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            else if (input.SystemEnvType == SystemEnvType.Resolution)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.Resolution } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label.ToString()
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.Resolution, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label.ToString(),
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            else if (input.SystemEnvType == SystemEnvType.ScreenColor)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.ColorDepth } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.ColorDepth, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label,
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            else if (input.SystemEnvType == SystemEnvType.Language)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.CultureName } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.CultureName, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label,
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            else if (input.SystemEnvType == SystemEnvType.Cookie)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.CookieEnabled } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label ? "支持cookie" : "不支持cookie"
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.CookieEnabled, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label ? "支持cookie" : "不支持cookie",
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label 
                        };
            }
            else if (input.SystemEnvType == SystemEnvType.Isp)
            {
                ipQuery = from dataTwo in
                              from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvQuery(input, TenancyName)
                              group data by new { Ip = data.ClientIp, Label = data.ISP } into t
                              select new
                              {
                                  Ip = t.Key.Ip,
                                  Label = t.Key.Label
                              }
                          group dataTwo by new { Label = dataTwo.Label } into tTwo
                          select new ClientIpQueryDto
                          {
                              IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                              Label = tTwo.Key.Label
                          };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvQuery(input, TenancyName)
                            group data by new { Label = data.ISP, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label,
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }
            

            var ipList = await ipQuery.ToListAsync();
            var list = await query.ToListAsync();

            var SystemEnvItems = new List<SystemEnvItem>();
            foreach (var item in list)
            {
                var SystemEnvItem = new SystemEnvItem();
                SystemEnvItem.Label = item.Label;
                SystemEnvItem.UvNum = item.UvNum;
                SystemEnvItem.PvNum = item.PvNum;
                SystemEnvItem.NewNum = item.NewNum;
                SystemEnvItem.LengthOfStay = item.LengthOfStay;
                SystemEnvItem.OutRate = _visitStatisticHelper.BounceRateCalc(item.OutNum, item.PvNum);
                SystemEnvItem.AvgVisitTime = _visitStatisticHelper.NumberToTime(item.LengthOfStay, item.PvNum, item.OutNum);

                SystemEnvOut.UvNum += item.UvNum;
                SystemEnvOut.PvNum += item.PvNum;
                SystemEnvOut.NewNum += item.NewNum;
                lengthOfStay += item.LengthOfStay;
                outNumber += item.OutNum;

                foreach (var p in ipList)
                {
                    if (item.Label == p.Label)
                    {
                        SystemEnvItem.IpNum = p.IpNum;
                        SystemEnvOut.IpNum += p.IpNum;
                    }
                }
                SystemEnvItems.Add(SystemEnvItem);
            }


            SystemEnvOut.OutRate = _visitStatisticHelper.BounceRateCalc(outNumber, SystemEnvOut.PvNum);
            SystemEnvOut.AvgVisitTime = _visitStatisticHelper.NumberToTime(lengthOfStay, SystemEnvOut.PvNum, outNumber);
            SystemEnvOut.SystemEnvItems = SystemEnvItems;
            return SystemEnvOut;
        }

        [AbpAuthorize(ASPermissions.Pages_Manage_AccessStatistics_Query)]
        public async Task<List<SystemDetailItem>> GetSystemEnvTaxonomyItems(SystemEnvTaxonomyInput input)
        {

            IQueryable<ClientIpQueryDto> ipQuery = null;
            IQueryable<AccoutDetailQueryDto> query = null;
            var TenancyName = GetCurrentTenant().TenancyName;
            if (input.Type == SystemEnvTaxonomyType.Browser)
            {
                ipQuery =
                            from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvDetailQuery(input, TenancyName)
                                group data by new { Ip = data.ClientIp, Label = data.BrowserFamily } into t
                                select new
                                {
                                    Ip = t.Key.Ip,
                                    Label = t.Key.Label
                                }
                            group dataTwo by new { Label = dataTwo.Label } into tTwo
                            select new ClientIpQueryDto
                            {
                                IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                Label = tTwo.Key.Label
                            };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvDetailQuery(input, TenancyName)
                            group data by new { Label = data.BrowserFamily, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label.ToString(),
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };

            }
            else
            {
                ipQuery =
                            from dataTwo in
                                from data in _AccessDataRespository.GetAll()
                              .VisitorSystemEnvDetailQuery(input, TenancyName)
                                group data by new { Ip = data.ClientIp, Label = data.OS } into t
                                select new
                                {
                                    Ip = t.Key.Ip,
                                    Label = t.Key.Label
                                }
                            group dataTwo by new { Label = dataTwo.Label } into tTwo
                            select new ClientIpQueryDto
                            {
                                IpNum = tTwo.Count(item => item.Ip != null && item.Ip != ""),
                                Label = tTwo.Key.Label
                            };

                query = from dataTwo in
                            from data in _AccessDataRespository.GetAll()
                            .VisitorSystemEnvDetailQuery(input, TenancyName)
                            group data by new { Label = data.OS, Accout = data.Acount } into t
                            select new
                            {
                                Account = t.Key.Accout,
                                Label = t.Key.Label.ToString(),
                                PvNum = t.Count(),
                                OutNum = t.Sum(item => item.IsBounced),
                                NewNum = t.Sum(item => item.IsNewVisitor),
                                LengthOfStay = t.Sum(item => item.LengthOfStay)
                            }
                        group dataTwo by new { Label = dataTwo.Label } into tTwo
                        select new AccoutDetailQueryDto
                        {
                            UvNum = tTwo.Count(item => item.Account != null && item.Account != ""),
                            PvNum = tTwo.Sum(item => item.PvNum),
                            NewNum = tTwo.Sum(item => item.NewNum),
                            OutNum = tTwo.Sum(item => item.OutNum),
                            LengthOfStay = tTwo.Sum(item => item.LengthOfStay),
                            Label = tTwo.Key.Label
                        };
            }

            var ipList = await ipQuery.ToListAsync();
            var list = await query.ToListAsync();

            var result = new List<SystemDetailItem>();
            foreach (var item in list)
            {
                var detail = new SystemDetailItem();
                detail.Label = item.Label;
                detail.LengthOfStay = item.LengthOfStay;
                detail.NewNum = item.NewNum;
                detail.PvNum = item.PvNum;
                detail.UvNum = item.UvNum;
                detail.OutRate = _visitStatisticHelper.BounceRateCalc(item.OutNum, item.PvNum);
                detail.AvgVisitTime = _visitStatisticHelper.NumberToTime(item.LengthOfStay, item.PvNum, item.OutNum);
                foreach (var p in ipList)
                {
                    if (p.Label == item.Label)
                    {
                        detail.IpNum = p.IpNum;
                    }
                }
                result.Add(detail);
            }
            return result;
                          
        }
    }
}
